﻿using System;
using System.Collections.Generic;
using System.Linq;
using QDT.Common;
using QDT.Core.Members;

namespace QDT.Core.Projects
{
    /// <summary>
    /// 理财投资项目类
    /// </summary>
    public class Project : Entity, IAggregeRoot
    {

        public Project()
        {
            CreateTime = DateTime.Now;
            Status = ProjectStatus.Wait;
            Sort = 0;
            IsEffect = true;
            IsDelete = false;
        }

        public Project(ParentProject parent, string name, string subName, decimal borrowAmount, decimal minLoanMoney, decimal maxLoanMoney)
            : this()
        {
            Check.Argument.IsNotNull(parent, "parent");

            ParentId = parent.ID;
            UserID = parent.UserId;
            Name = name;
            SubName = subName;
            BorrowAmount = borrowAmount;
            MinLoanMoney = minLoanMoney;
            MaxLoanMoney = maxLoanMoney;
            InnerStatus = (int)ProjectStatus.Wait;

            TypeID = parent.TypeId;
            RepaymentID = parent.RepaymentId;
            RepayTime = parent.RepayTime;
            RepayTimeType = parent.RepayTimeType;
            Rate = parent.Rate;
            SettleDay = parent.SettleDay;
        }

        /// <summary>
        /// 项目名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 项目简称
        /// </summary>
        public string SubName { get; set; }

        /// <summary>
        /// 用户ID
        /// </summary>
        public int UserID { get; private set; }

        /// <summary>
        /// 项目类型ID
        /// </summary>
        public int TypeID { get; private set; }

        /// <summary>
        /// 是否有效
        /// </summary>
        public bool IsEffect { get; set; }

        /// <summary>
        /// 是否删除
        /// </summary>
        public bool IsDelete { get; set; }
        /// <summary>
        /// 排序
        /// </summary>
        public int Sort { get; set; }

        /// <summary>
        /// 还款方式
        /// </summary>
        public int RepaymentID { get; private set; }

        /// <summary>
        /// 还款限期，当RepayTimeType为0的时候代表天数，当RepayTimeType为1的时候代表月数
        /// </summary>
        public int RepayTime { get; private set; }

        /// <summary>
        /// 还款时间类型，0代表天，1代表月
        /// </summary>
        public int RepayTimeType { get; private set; }

        /// <summary>
        /// 利率（利率单位为小数点后2位，如 12代表的是12% ，作为利率计算需要除以100）
        /// </summary>
        public double Rate { get; private set; }

        /// <summary>
        /// 借款金额
        /// </summary>
        public decimal BorrowAmount { get; set; }

        /// <summary>
        /// 最小投资金额
        /// </summary>
        public decimal MinLoanMoney { get; set; }

        /// <summary>
        /// 最大投资金额
        /// </summary>
        public decimal MaxLoanMoney { get; set; }

        public int InnerStatus { get; private set; }

        /// <summary>
        /// 项目状态
        /// </summary>
        public ProjectStatus Status
        {
            get { return (ProjectStatus)InnerStatus; }
            set { InnerStatus = (int)value; }
        }

        /// <summary>
        /// 已经融到的总金额
        /// </summary>
        public decimal LoadMoney { get; set; }

        /// <summary>
        /// 已经还款总金额（包括利息）
        /// </summary>
        public decimal RepayMoney { get; set; }

        /// <summary>
        /// 结算日,0或-1表示不使用结算日
        /// </summary>
        public int SettleDay { get; private set; }

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreateTime { get; private set; }

        /// <summary>
        /// 开始时间
        /// </summary>
        public DateTime? StartTime { get; set; }

        /// <summary>
        /// 还款开始时间
        /// </summary>
        public DateTime? RepayStartTime { get; set; }

        /// <summary>
        /// 还款结束时间
        /// </summary>
        public DateTime? RepayEndTime { get; set; }

        /// <summary>
        /// 最后一次还款时间
        /// </summary>
        public DateTime? LastRepayTime { get; set; }

        /// <summary>
        /// 下一次还款时间
        /// </summary>
        public DateTime? NextRepayTime { get; set; }

        /// <summary>
        /// 流标时间
        /// </summary>
        public DateTime? BadTime { get; set; }

        /// <summary>
        /// 已经还款期数
        /// </summary>
        public int CurrentStage { get; set; }

        /// <summary>
        /// 总的期数
        /// </summary>
        public int TotalStage { get; set; }

        /// <summary>
        /// 协议连接
        /// </summary>
        public string AgreementLink { get; set; }

        /// <summary>
        /// 是否线下
        /// </summary>
        public bool IsOffline { get; set; }

        /// <summary>
        /// 能否转让
        /// </summary>
        public bool AssignAble { get; set; }

        /// <summary>
        /// 总项目ID
        /// </summary>
        public int ParentId { get; private set; }

        /// <summary>
        /// 项目ID
        /// </summary>
        public virtual ParentProject Parent { get; set; }

        /// <summary>
        /// 时间戳（数据库锁）
        /// </summary>
        public byte[] TimeStamp { get; set; }

        /// <summary>
        /// 扩展属性值
        /// </summary>
        public virtual ICollection<ProjectExtend> ExtendAttributes { get; set; }

        /// <summary>
        /// 返回指定属性的属性值，如果不存在，返回string.empty
        /// </summary>
        /// <param name="fieldID"></param>
        /// <returns></returns>
        public string GetAttribute(int fieldID)
        {
            var attr = ExtendAttributes.ToList().FirstOrDefault(x => x.FeildID == fieldID);
            return attr == null ? "" : attr.Value;
        }

        /// <summary>
        /// 获得投标进度
        /// </summary>
        public double Progress
        {
            get { return Math.Floor(Convert.ToDouble(LoadMoney / BorrowAmount * 100)); }
        }

        /// <summary>
        /// 可投余额
        /// </summary>
        public decimal NeedMoney
        {
            get { return BorrowAmount - LoadMoney; }
        }

        /// <summary>
        /// 满标
        /// </summary>
        public void SetFullStatus()
        {

            if (this.Status != ProjectStatus.Progress) throw new Exception("错误操作：当前标状态({0})不能设置满标.".FormatWith(this.Status.ToString()));

            this.Status = ProjectStatus.Full;
        }

        /// <summary>
        /// 审核材料
        /// </summary>
        /// <param name="isValid"></param>
        public void SetApproveStatus(bool isValid, string remark = "")
        {

            if (this.Status != ProjectStatus.Wait) throw new Exception("错误操作：当前状态（{0}）不能进行审核操作.".FormatWith(this.Status.ToString()));

            if (isValid)
            {
                this.Status = ProjectStatus.Progress;
            }
        }

        /// <summary>
        /// 流标
        /// </summary>
        public void SetBadStatus()
        {

            if (this.Status != ProjectStatus.Progress) throw new Exception("错误操作：当前状态({0})不能进行流标操作.".FormatWith(this.Status.ToString()));

            this.Status = ProjectStatus.Bad;
            this.BadTime = DateTime.Now;

        }

        /// <summary>
        /// 划款
        /// </summary>
        /// <param name="start"></param>
        public void SetReplayStatus(DateTime start, int total)
        {

            if (this.Status != ProjectStatus.Full) throw new Exception("错误操作：当前状态({0})不能设置还款中操作.".FormatWith(this.Status.ToString()));

            this.RepayStartTime = start;
            if (RepayTimeType == 0)
            {
                this.RepayEndTime = start.AddDays(this.RepayTime);
            }
            if (RepayTimeType == 1)
            {
                this.RepayEndTime = start.AddMonths(this.RepayTime);
            }
            if (RepayTimeType != 0 && RepayTimeType != 1)
            {
                throw new Exception();
            }

            this.Status = ProjectStatus.Repaying;
        }


        //还款结束
        public void SetRepaidStatus()
        {

            if (this.Status != ProjectStatus.Repaying) throw new Exception("错误操作：当前状态({0})不能设置还款结束操作.".FormatWith(this.Status.ToString()));

            this.Status = ProjectStatus.Repaid;

        }

    }
}
